home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 282_01 / walclock.c < prev    next >
Text File  |  1989-01-11  |  18KB  |  870 lines

  1. /*
  2. TITLE:        Wall Clock;
  3. DATE:        9/19/88;
  4. DESCRIPTION:    "Analog clock face.";
  5. VERSION:    1.10;
  6. KEYWORDS:    Clock, Graphics, HGA, Hercules;
  7. FILENAME:    WALCLOCK.C
  8. WARNINGS:    "Requires Hercules monochrome graphics.";
  9. SEE-ALSO:    WALCLOCK.DAT, WALCLOCK.EXE;
  10. SYSTEM:        MS-DOS;
  11. COMPILERS:    Aztec;
  12. AUTHORS:    Dan Schechter;
  13.  */
  14. #include <stdio.h>
  15. #include <time.h>
  16. #include <math.h>
  17.  
  18. #define TICKTOCK    /* Delete this if you don't want the tick-tock. */
  19. #define NOMATH        /* Delete this if the program will always be
  20.             run on a computer with a floating-point coprocessor
  21.             and your compiler has FPU support. With NOMATH
  22.             defined, the program uses a table look-up to 
  23.             position the hands. This makes the program about twice
  24.             as large. If NOMATH is not defined, the program
  25.             calculates the positions of hands on the fly, but
  26.             an FPU is necessary if this is to be done fast enough
  27.             to keep up with real time. */
  28. #ifdef TICKTOCK
  29. #include <signal.h>
  30. #endif
  31.  
  32. #ifdef NOMATH
  33. #define VERSION "Version 1.10-t 9/19/88" 
  34. #else
  35. #define VERSION "Version 1.10-fpu 9/19/88" 
  36. #endif
  37.  
  38. #define CENTERH 360
  39. #define CENTERV 174
  40. #define TOPH 360
  41. #define TOPV 25
  42. #define LONG 125
  43. #define SHORT 75
  44.  
  45. #define INDEXPORT 0x3B4
  46. #define CONTROLPORT 0x3b8
  47. #define DATAPORT 0x3b5
  48. #define CONFIGPORT 0x3bf
  49. #define SCREEN0 0xb0000     /* Absolute address for page 0. */
  50. #define SCREEN1 0xb8000     /* Absolute address for page 1. */
  51. #define ROMFONT 0xffa6e       /* Absolute address of IBM ROM character set. */
  52.  
  53. void drawclock(void), controller(void), line(int,int,int,int,int), 
  54.      gocircle(int,int), _drawclock(void), 
  55.      hand(int,int,int,int,int), writetd(int,int,int,int, struct tm *), 
  56.      markers(void), g_write(char *,int,int), sigexit(int), cleardot(int,int), 
  57.      reagantime(struct tm *), chinatime(void), menu(void), 
  58.      stepclock(void), writedot(int,int), g_putch(int,int,int), sw_scr(int), 
  59.      g_mode(void), t_mode(void), *abstoptr(unsigned long),
  60.      tick(void), soundon(void), soundoff(void), tick_init(void);
  61.  
  62. int  sqroot(long);
  63.  
  64. char *day[7] = {
  65.     "Sunday   ",
  66.     "Monday   ",
  67.     "Tuesday  ",
  68.     "Wednesday",
  69.     "Thursday ",
  70.     "Friday   ",
  71.     "Saturday "
  72. };
  73. char *month[12] = {
  74.     "January ",
  75.     "February ",
  76.     "March ",
  77.     "April ",
  78.     "May ",
  79.     "June ",
  80.     "July ",
  81.     "August ",
  82.     "September ",
  83.     "October ",
  84.     "November ",
  85.     "December "
  86. };
  87.  
  88. int gdata[12] = { 
  89.     0x35, 0x2d, 0x2e, 0x7, 0x5b, 0x2, 0x57, 0x57, 0x2, 0x3, 0x0, 0x0 
  90. };
  91. int tdata[12] = { 
  92.     0x61, 0x50, 0x52, 0xf, 0x19, 0x6, 0x19, 0x19, 0x2, 0xd, 0xb, 0xc 
  93. };
  94.  
  95. int h24[24] = { 53, 61, 68, 73, 76, 77, 76, 73, 69, 60, 52, 44,
  96.         36, 28, 21, 16, 13, 12, 13, 16, 21, 28, 36, 44 };
  97. int v24[24] = { 5, 20, 48, 86, 128, 171, 215, 256, 296, 318, 333, 340,
  98.         333, 321, 293, 257, 214, 170, 127, 82, 45, 20, 5, 0 };
  99. int h12[12] = { 61, 73, 77, 73, 61, 45, 29, 17, 13, 16, 28, 44 };
  100. int v12[12] = { 20, 86, 171, 256, 318, 340, 318, 257, 170, 82, 20, 0 };
  101.  
  102. char *numbers12[12] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", 
  103.             "11", "12" };
  104. char *numbers24[24] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", 
  105.             "11", "12", "13", "14", "15", "16", "17", "18", 
  106.             "19", "20", "21", "22", "23", "24" };
  107. char *numbers12_a[12] = { "11", "10", "9", "8", "7", "6", "5", "4", "3", 
  108.             "2", "1", "12" };
  109. char *numbers24_a[24] = { "23", "22", "21", "20", "19", "18", "17", "16", 
  110.             "15", "14", "13", "12", "11", "10", "9", "8", "7", 
  111.             "6", "5", "4", "3", "2", "1", "24" };
  112.  
  113. thymelimit[7] = { 60, 60, 24, 0, 12, 99, 7 };
  114. monthlimit[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  115.  
  116. unsigned char *screen, *screen0, *screen1, *font ; 
  117. int *thyme[7];
  118. char twentyfour=0,location='l';
  119.  
  120. int main()
  121. {
  122.     
  123.     screen0=abstoptr(SCREEN0);
  124.     screen=screen1=abstoptr(SCREEN1);
  125.     font=abstoptr(ROMFONT);
  126.     system("break off");
  127.     g_mode();
  128. #ifdef TICKTOCK
  129.     signal (SIGINT, (void (*)(int)) sigexit);
  130.     tick_init();
  131. #endif
  132.     drawclock();
  133.     controller();
  134.     t_mode();
  135.     scr_clear();
  136.     exit(0);
  137. }
  138.  
  139. void drawclock()
  140. {
  141.     
  142.     int x,y,off,cx=CENTERH,cy=CENTERV,ex=TOPH,ey=TOPV;
  143.     long r,xr,yr,xx,yy;
  144.     
  145.     sw_scr(-1);
  146.     xr=cx-ex;
  147.     yr=cy-ey;
  148.     r=sqroot((xr*xr)+(yr*yr))+1;
  149.     off=(r*100)/141;
  150.     
  151.     gocircle(cy+(int)r-1,cx);
  152.     gocircle(cy-(int)r+1,cx);
  153.     
  154.     for(x=1;x<=off;x++){
  155.         xx=x;
  156.         xx*=xx;
  157.         y=sqroot(r*r-xx);
  158.         gocircle(cy+y,cx+x);
  159.         gocircle(cy+y,cx-x);
  160.         gocircle(cy-y,cx+x);
  161.         gocircle(cy-y,cx-x);
  162.      }
  163.     
  164.     gocircle(cy,cx+(int)r-1);
  165.     gocircle(cy,cx-(int)r+1);
  166.     
  167.     for(y=1;y<=off;y++){
  168.         yy=y;
  169.         yy*=yy;
  170.         x=sqroot(r*r-yy);
  171.         gocircle(cy+y,cx+x);
  172.         gocircle(cy+y,cx-x);
  173.         gocircle(cy-y,cx+x);
  174.         gocircle(cy-y,cx-x);
  175.     }
  176.     markers();
  177.     g_write("WALLCLOCK - KITTENSOFT",340,0);
  178.     g_write(VERSION,340,64);
  179.     
  180.     if (twentyfour)
  181.         for (x=0;x<24;x++) {
  182.             if (location=='a') 
  183.                 g_write(numbers24_a[x],v24[x],h24[x]);
  184.             else 
  185.                 g_write(numbers24[x],v24[x],h24[x]);
  186.         }
  187.     else
  188.         for (x=0;x<12;x++){
  189.             if (location=='a')
  190.                 g_write(numbers12_a[x],v12[x],h12[x]);
  191.             else 
  192.                 g_write(numbers12[x],v12[x],h12[x]);
  193.         }
  194.     menu();
  195.     memcpy(screen1,screen0,32767);
  196. }
  197.  
  198. void controller()
  199. {
  200.     int s,m,h,dh,dm,os,odm,odh,oos,oodm,oodh,q,h24;
  201.     struct tm t;
  202.     char meridian;
  203.     
  204.     thyme[0]=&(t.tm_sec);
  205.     thyme[1]=&(t.tm_min);
  206.     thyme[2]=&(t.tm_hour);
  207.     thyme[3]=&(t.tm_mday);
  208.     thyme[4]=&(t.tm_mon);
  209.     thyme[5]=&(t.tm_year);
  210.     thyme[6]=&(t.tm_wday);
  211.  
  212.     os=odm=odh=s=dm=dh=1;
  213.     for(;;){
  214.         switch (inkey()){
  215.             case 'X':
  216.             case 'q':
  217.             case 'Q':
  218.             case 'x': 
  219.             case 3:
  220.                 return;
  221.             case 'a': 
  222.             case 'A':
  223.                 location='a';
  224.                 os=odm=odh=s=dm=dh=1;
  225.                 drawclock();
  226.                 break;
  227.             case 'l':
  228.             case 'L':
  229.                 location='l';
  230.                 os=odm=odh=s=dm=dh=1;
  231.                 drawclock();
  232.                 break;
  233.             case 'c':
  234.             case 'C':
  235.                 dostime(&t);
  236.                 location='c';
  237.                 os=odm=odh=s=dm=dh=1;
  238.                 drawclock();
  239.                 break;
  240.             case 'r':
  241.             case 'R':
  242.                 location='r';
  243.                 os=odm=odh=s=dm=dh=1;
  244.                 drawclock();
  245.                 break;
  246.             case '\t':
  247.                 twentyfour ^=1;
  248.                 os=odm=odh=s=dm=dh=1;
  249.                 drawclock();
  250.                 break;
  251.             case 0: break;
  252.         }
  253.         oos=os;
  254.         oodm=odm;
  255.         oodh=odh;
  256.         os=s;
  257.         odm=dm;
  258.         odh=dh;
  259.         switch (location) {
  260.             case 'c': 
  261.                 chinatime(); 
  262.                 break;
  263.             case 'r': 
  264.                 reagantime(&t); 
  265.                 break;
  266.             case 'a':
  267.             case 'l':
  268.                 do dostime(&t);
  269.                 while (os==t.tm_sec); 
  270.                 break;
  271.         }
  272.         sw_scr(0);
  273. #ifdef TICKTOCK
  274.         tick();
  275. #endif
  276.         s=t.tm_sec;
  277.         m=t.tm_min;
  278.         h=t.tm_hour;
  279.         dh=h;
  280.         if (twentyfour==0){        
  281.             if (dh>11) dh-=12;
  282.             if (h>11) meridian='P';
  283.             else meridian='A';
  284.             if (h>12) h-=12;
  285.             if (h==0) h=12;
  286.         }
  287.         dh= dh*60+m;
  288.         dm= m*6+s/10;
  289.         
  290.         hand(oos,60,LONG,0,'e');
  291.         if (oodm!=dm) hand(oodm,360,LONG,1,'e');
  292.         if (oodh!=dh) {
  293.             if (twentyfour) hand(oodh,1440,SHORT,1,'e');
  294.             else hand(oodh,720,SHORT,1,'e');
  295.         }
  296.         hand(s,60,LONG,0,'d');
  297.         hand(dm,360,LONG,1,'d');
  298.         if (twentyfour) hand(dh,1440,SHORT,1,'d');
  299.         else hand(dh,720,SHORT,1,'d');
  300.         writetd(s,m,h,meridian,&t);
  301.     }
  302. }
  303.  
  304. /* The following toggles the active screen (the one being displayed)
  305. and also toggles the screen pointer (the one being written to) so that
  306. the program is always displaying the screen not being written to. */
  307.  
  308. void sw_scr(q)
  309. int q;
  310. {
  311.     static int scr;
  312.     
  313.     if (q==-1){
  314.         screen=screen1;
  315.         scr = 0;
  316.         memset(screen0,0,32767);
  317.         memset(screen1,0,32767);
  318.         outportb(CONTROLPORT, 10 | scr);
  319.         g_write("Please stand by...",100,30);
  320.     }
  321.     scr ^= 128;
  322.     outportb(CONTROLPORT, 10 | scr);
  323.     if (screen==screen0) screen=screen1;
  324.     else screen=screen0;
  325. }
  326.  
  327. #ifdef NOMATH
  328. #include "clock.dat"
  329.  
  330. void hand(n,num,length,w,q)
  331. int n,num,length,w,q;
  332. {
  333.     int v,h;
  334.     
  335.     switch (num) {
  336.         case 60: n*=6; break;
  337.         case 720: n*=2; break;
  338.     }
  339.     switch (length) {
  340.         case LONG: 
  341.             h=hlong[n];
  342.             v=vlong[n];
  343.             break;
  344.         case SHORT:
  345.             h=hshort[n];
  346.             v=vshort[n];
  347.             break;
  348.     }
  349.  
  350.     if (location=='a') h=((h-CENTERH)*(-1))+CENTERH; /* Austrailia */
  351.     
  352.     line(h,v,CENTERH,CENTERV,q);
  353.  
  354.     if (w) {
  355.         line(h+1,v,CENTERH+1,CENTERV,q);
  356.         line(h,v+1,CENTERH,CENTERV+1,q);
  357.  
  358. /* The following 3 lines give the hands better bredth. But they are
  359. very time consuming. Delete them if the